package com.frxuexi.lib_base

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.frxuexi.lib_base.download.DownloadUtil
import com.frxuexi.lib_base.scan.LocalUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

abstract class BaseViewModel<UiIntent : IUiIntent, UIState : UiState<Any>> : ViewModel() {
    private val _uiIntent = Channel<UiIntent>(Channel.UNLIMITED)


    private val _uiState = MutableStateFlow<UiState<Any>>(UiState.onLoading)
    val uiState: StateFlow<UiState<Any>>
        get() = _uiState

    init {
        viewModelScope.launch {
            _uiIntent.consumeAsFlow().collect {
                handlerIntent(it)
            }
        }
    }

    /**
     * 处理意图
     */
    abstract fun handlerIntent(intent: UiIntent)

    /**
     * 发送意图
     */
    fun sendIntent(intent: UiIntent) {
        viewModelScope.launch {
            _uiIntent.send(intent)
        }
    }

    fun sendState(copy: (UiState<Any>) -> UiState<Any>) {
        _uiState.update { copy(_uiState.value) }
    }

    fun httpRequest(request: Flow<ApiResponse<Any>>, type: RequestType = RequestType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch { ex ->
                    ex.printStackTrace()
                    sendState { ex.message?.let { it1 -> UiState.onError(it1) } as UIState }
                }
                .collect { resp ->
                    if (resp.statusCode == 200) {
                        val data = resp.data
                        if (data != null)
                            sendState { UiState.onSuccess(resp.data, type) as UIState }
                        else {
                            sendState { UiState.onSuccess(resp.datas, type) as UIState }
                        }
                    } else {
                        sendState { resp.msg?.let { it1 -> UiState.onError(it1) } as UIState }
                    }
                }
        }
    }


    fun roomRequest(request: Flow<Any>, type: RequestType = RequestType.DEFAULT) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch { ex ->
                    ex.printStackTrace()
                    sendState { ex.message?.let { it1 -> UiState.onError(it1) } as UIState }
                }
                .collect { resp ->
                    if (resp != null) {
                        sendState { UiState.onSuccess(resp, type) as UIState }
//                        _uiState.value=UiState.onSuccess(resp, type)
                    } else {
                        sendState { UiState.onError("操作失败") } as UIState
                    }
                }
        }
    }


    fun downloadApk(url: String, path: String) {
        viewModelScope.launch {
            DownloadUtil.download(url, path).flowOn(Dispatchers.IO)
                .catch { ex ->
                    Log.i("===", ex.message.toString())
                }.collect {
                    _uiState.value = it
                }
        }
    }

    fun scanLocal(path: String) {
        viewModelScope.launch {
            LocalUtil.getLocalFiles(path)
                .flowOn(Dispatchers.IO)
                .catch {
                    _uiState.value = it.message?.let { it1 -> UiState.onError(it1) }!!
                }
                .collect {
                    _uiState.value = UiState.onSuccess(it, RequestType.LOCAL_FILE)
                }
        }
    }

}